package com.mcflywzx.airhockey.util;

import com.mcflywzx.airhockey.util.Geometry.Plane;
import com.mcflywzx.airhockey.util.Geometry.Point;
import com.mcflywzx.airhockey.util.Geometry.Ray;

import android.util.FloatMath;

public class Geometry {
	
	public static class Point {
		public float x, y, z;
		public Point(float x, float y, float z) {
			this.x = x;
			this.y = y;
			this.z = z;
		}
		
		public Point setY(float sy) {
			return new Point(x, sy, z);
		}
		
		public Point translateY(float distance) {
			return new Point(x, y + distance, z);
		}
		
		public Point translate(Vector v) {
			return new Point(
					x + v.x, 
					y + v.y, 
					z + v.z);
		}
	}
	
	public static class Vector {
		public float x, y, z;
		
		public Vector(float x, float y, float z) {
			this.x = x;
			this.y = y;
			this.z = z;
		}
		
		public float length() {
			return (float) Math.sqrt(x * x + y * y + z * z);
		}
		
		public Vector crossProduct(Vector other) {
			return new Vector(
					(y * other.z) - (z * other .y),
					(z * other.x) - (x * other .z),
					(x * other.y) - (y * other .x));
		}

		public float doProduct(Vector other) {
			// TODO Auto-generated method stub
			return x * other.x
					+  y * other.y
					+	z * other.z;
		}

		public Vector scale(float f) {
			// TODO Auto-generated method stub
			return new Vector(
					x * f,
					y * f,
					z * f);
		}
	}

	public static class Ray {
		public final Point p;
		public final Vector v;
		
		public Ray(Point p, Vector v) {
			this.p = p;
			this.v = v;
		}
		
	}
	
	public static class Plane {
		public  Point p;
		public  Vector normal;
		
		public Plane(Point p, Vector normal) {
			this.p = p;
			this.normal = normal;
		}
	}
	
	public static class Cube {
		public  final Point position;
		public  final float L, W, H;
		
		public Cube(Point position, float L, float W, float H) {
			this.position = position;
			this.L = L;
			this.W = W;
			this.H = H;
		}
	}
	
	public static class Circle {
		public final Point center;
		public final float r;
		
		public Circle(Point center, float r) {
			this.center = center;
			this.r = r;
		}
		
		public Circle scale(float scale) {
			return new Circle(center, r * scale);
		}
	}
	
	public static class Sphere {
		public final Point center;
		public final float r;
		
		public Sphere(Point center, float r) {
			this.center = center;
			this.r = r;
		}
	}
	
	public static class Cylinder { //圆柱
		public final Point position;
		public final float r;
		public final float h;
		
		public Cylinder(Point position, float r, float h) {
			this.position = position;
			this.r = r;
			this.h = h;
		}
	}
	
	public static Vector vectorBetween(Point from, Point to) {
		return new Vector (
				to.x - from.x,
				to.y - from.y,
				to.z - from.z);
	}
	
	public static float distanceBetween(Point p, Ray ray) {
		Vector p1ToPoint = vectorBetween(ray.p, p);
		Vector p2ToPoint = vectorBetween(ray.p.translate(ray.v), p);
		
		float a = p1ToPoint.crossProduct(p2ToPoint).length();
		float lengthOfBase = ray.v.length();
		
		float d = a / lengthOfBase;
		return d;
	}
	
	public static boolean intesects(Sphere sphere, Ray ray) {
		return distanceBetween(sphere.center, ray) < sphere.r;
	}
	

	public static Point intersectionPoint(Ray ray, Plane plane) {
		// TODO Auto-generated method stub
		Vector rayToPlaneVector = vectorBetween(ray.p, plane.p);
		
		float scaleFactor = rayToPlaneVector.doProduct(plane.normal) / ray.v.doProduct(plane.normal);
		
		return ray.p.translate(ray.v.scale(scaleFactor));
	}
}
